package com.hntxk.cqzd.lis.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.google.common.io.CharStreams;
import com.hntxk.core.framework.service.impl.BaseServiceImpl;
import com.hntxk.core.util.DateUtil;
import com.hntxk.core.util.StringUtil;
import com.hntxk.cqzd.common.util.ComparatorDateLis;
import com.hntxk.cqzd.common.util.ComparatorDatePacs;
import com.hntxk.cqzd.lis.model.*;
import com.hntxk.cqzd.lis.service.LisInterfaceService;
import com.hntxk.sp.dict.manager.DictManager;
import com.mchange.lang.IntegerUtils;
import lombok.extern.slf4j.Slf4j;
import lombok.val;
import org.apache.commons.io.Charsets;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.SocketTimeoutException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;

@Service
@Component("LisInterfaceServiceImpl")
@Slf4j
public class LisInterfaceServiceImpl extends BaseServiceImpl<LisModel> implements LisInterfaceService {

    /**
     * 定时请求Lis数据
     * @return
     */
    @Override
    public List<LisModel> getLis(String outpatientNo, Integer dict){
        Integer it =1;
        if (dict!=null){
            it = dict;
        }

        List<LisModel> lisModels = new ArrayList<>();
        List<Object> objects = getDasTemplate().selectList("com.hntxk.cqzd.pacs.mapper.PacsInterfaceMapper.selectHis",outpatientNo);
        if (ObjectUtils.isEmpty(objects)){
            return lisModels;
        }
        HttpClient httpclient;
        HttpGet httpGet;
        HttpResponse response;
        for (Object o:objects) {
            try {
                String lis = o.toString();
                //        测试地址
//                String uri = "http://127.0.0.1:8008/commom/file/cesLis";
//                String uri = DictManager.getInstance().getDict("CQ_LIS_IFACE",it).getText()+outpatientNo;
                String uri = DictManager.getInstance().getDict("CQ_LIS_IFACE",it).getText()+lis;
                httpclient = new DefaultHttpClient();
                httpGet = new HttpGet(uri);
                // 添加http头信息
//            Date businessTime = new Date(); // 业务时间，查询接口可不填
//                String uuid =UUID.randomUUID().toString().replace("-","");
                Date operationTime = new Date(); // 调用此接口的系统时间，一般是调用平台接口时new当时时间
                httpGet.addHeader("Content-Type", "application/fhir+json");
                httpGet.addHeader("rootId", "2a15ce2b-f4f9-4599-9b2b-2c29b8378374"); // 调用方存储日志的id，用于追溯日志
                httpGet.addHeader("token", "acae2b21-34b8-47eb-adec-6a2fbd51dc52"); // 调用接口中的业务号，例如使用患者流水号查询检验报告接口，此处填写患者就诊流水号
                httpGet.addHeader("businessTime", ""); // 此接口对应的业务时间，如果是查询接口可不填
                httpGet.addHeader("domain", "CHANQIANZD"); // 调用此接口的系统域，例如LIS、HIS、SPD
                httpGet.addHeader("key", "ad0ce7db-40d9-4d85-8839-62c3b438aba3"); // 调用此接口的授权码，与系统域对应，一般是总线维护的授权码
                httpGet.addHeader("operationTime", DateUtil.getStrByFormat( operationTime,"yyyy-MM-dd HH:mm:ss")); // 调用此接口的系统时间，一般是调用平台接口时new当时时间

                response = httpclient.execute(httpGet);
                // 检验状态码，如果成功接收数据
                InputStream out = response.getEntity().getContent();
                String result = CharStreams.toString(new InputStreamReader(out, Charsets.UTF_8));
//                System.out.println(result);
                JSONObject jsonObject = JSON.parseObject(result);
                JSONArray entry = (JSONArray) jsonObject.get("entry");
//                json详情可以看common包下面的action的json.json
                if(entry!=null&&entry.size()>0) {
//                    List<Entry> entries = JSON.parseArray(entry.toJSONString(),Entry.class);
//                    for (Entry anEntry : entries)
                        for (int i = 0; i <entry.size() ; i++) {
//                            Entry anEntry = entry.get(i);
                        LisModel lisModel = new LisModel();
//                        Entry object = (Entry) anEntry;
                        JSONObject object =(JSONObject) entry.get(i);
                        if (object != null) {
                            JSONObject entryJson = (JSONObject) object.get("resource");
                            if (entryJson!=null)
                            /*if (entryJson != null)*/ {
                                Resource resource = JSON.parseObject(entryJson.toJSONString(), Resource.class);
//                                获取报告时间
                                if (resource.getEffectiveDateTime()!=null){
                                    lisModel.setEffectiveDateTime(resource.getEffectiveDateTime());
                                }
                                /*if (resource.getEffectiveDateTime()!=null){
                                    lisModel.setEffectiveDateTime(resource.getEffectiveDateTime());
                                }*/
//                                Resource resource = anEntry.getResource();
//                                解析resource下的contained获得报告结果
                                if(ObjectUtils.isNotEmpty(resource.getContained())){
                                    for(Contained ced :resource.getContained()){
                                        /*if (null!=ced.getCode()){
                                            if (ced.getCode().getEffectiveDateTime()!=null){
                                                lisModel.setEffectiveDateTime(ced.getCode().getEffectiveDateTime());
                                            }
                                        }*/
                                        if (ced.getValueQuantity() != null) {
                                            ValueQuantity valueQuantity = ced.getValueQuantity();
                                            if (valueQuantity.getExtension() != null && valueQuantity.getExtension().size() > 0) {
                                                List<Extension> extension = valueQuantity.getExtension();
                                                outer : for (Extension e : extension) {
                                                    if (lisModel.getResult()!=null){
                                                        continue;
                                                    }
                                                    Code code = ced.getCode();
                                                    if (code !=null){
                                                        List<Coding> codings = code.getCoding();
                                                        if (!codings.isEmpty()){
                                                            for (Coding coding:codings) {
                                                                if (coding.getDisplay().contains("荧光原位杂交")){
                                                                    break outer;
                                                                }
                                                            }
                                                        }
                                                    }
                                                    if (e.getUrl().contains("Naming/Observation/result")) {
                                                        lisModel.setResult(e.getValueString());
                                                    }

                                                }
                                            }
                                        }
                                        if(ced.getType() != null){
                                            Type cedType= ced.getType();
                                            if (cedType.getCoding() != null && cedType.getCoding().size()>0){
                                                List<Coding> codings = cedType.getCoding();
                                                //        存放type，因为接口返回是数组类型
                                                List<String> typ = new ArrayList<>();
                                                for (Coding cod:codings) {
                                                    if ("CodeSystem/Specimen/specimenType".equals(cod.getSystem())){
                                                        if (StringUtils.isNotEmpty(cod.getDisplay()))
                                                            typ.add(cod.getDisplay());
                                                    }
                                                }
                                                lisModel.setTypes(typ);
                                            }
                                        }

                                    }
                                }
                               /* if (resource.getValueQuantity() != null) {
                                    ValueQuantity valueQuantity = resource.getValueQuantity();
                                    if (valueQuantity.getExtension() != null && valueQuantity.getExtension().size() > 0) {
                                        List<Extension> extension = valueQuantity.getExtension();
                                        for (Extension e : extension) {
                                            if (e.getValueCoding().getDisplay() != null) {
                                                lisModel.setResult(e.getValueCoding().getDisplay());
                                            }
                                        }
                                    }
                                }*/
                               if (resource.getExtension() != null && resource.getExtension().size()>0){
                                   List<Extension> extension = resource.getExtension();
                                   for (Extension e:extension) {

                                       if (e.getUrl().contains("labReportResultDescription")) {
                                           if(lisModel.getResult()==null){
                                               lisModel.setResult(e.getValueString());
                                           }
                                       }
                                   }
                                   if (lisModel.getResult()==null){
                                       if(ObjectUtils.isNotEmpty(resource.getContained())){
                                           for(Contained ced :resource.getContained()) {
                                        /*if (null!=ced.getCode()){
                                            if (ced.getCode().getEffectiveDateTime()!=null){
                                                lisModel.setEffectiveDateTime(ced.getCode().getEffectiveDateTime());
                                            }
                                        }*/
                                               if (ced.getValueQuantity() != null) {
                                                   ValueQuantity valueQuantity = ced.getValueQuantity();
                                                   if (valueQuantity.getExtension() != null && valueQuantity.getExtension().size() > 0) {
                                                       List<Extension> extensionOuth = valueQuantity.getExtension();
                                                       for (Extension e : extensionOuth) {
                                                           if (lisModel.getResult() != null) {
                                                               continue;
                                                           }
                                                           if (e.getUrl().contains("Naming/Observation/result")) {
                                                               lisModel.setResult(e.getValueString());
                                                           }
                                                       }
                                                   }
                                               }
                                           }
                                       }
                                   }
                               }
//                                解析category
                                if (resource.getCategory() != null) {
                                    Category category = resource.getCategory();
                                    if (category.getCoding() != null && category.getCoding().size() > 0) {
                                        List<Coding> coding = category.getCoding();
                                        for (Coding c : coding) {
                                            if (c.getDisplay() != null) {
                                                lisModel.setCategoryCode(c.getDisplay());
                                            } else {
                                                if (resource.getCode() != null) {
                                                    Code code = resource.getCode();
                                                    if (code.getCoding() != null && code.getCoding().size() > 0) {
                                                        List<Coding> cod = code.getCoding();
                                                        for (Coding cd : cod) {
                                                            if (cd.getDisplay() != null) {
                                                                lisModel.setCategoryCode(cd.getDisplay());
                                                            }
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                        if (StringUtil.isNull(lisModel.getCategoryCode())) {
                                            lisModel.setCategoryCode("请点击下方url查看");
                                        }

                                    }
                                }
                                lisModel.setConclusion(resource.getConclusion());
                                //获得报告url
                                if (resource.getPresentedForm() != null) {
                                    List<PresentedForm> presentedForms = resource.getPresentedForm();
                                    if (presentedForms != null && presentedForms.size() > 0) {
                                        for (PresentedForm p : presentedForms) {
                                            if (StringUtil.isNotNull(p.getUrl())) {
                                                lisModel.setUrl(p.getUrl());
                                            }
                                        }
                                    }

                                }
//                                int code = response.getStatusLine().getStatusCode();
                            }
                            lisModel.setOutPatientNo((String) o);
                            lisModel.setCardId(outpatientNo);
                            lisModels.add(lisModel);
                            log.info(lisModel.getUrl()+":::"+lisModel.getTypes()+"::::"+lisModel.getResult());
                        }
                    }
                }
            }catch (Exception e) {
                log.error("lis接口错误,"+e.getMessage());
            }
        }
        ComparatorDateLis c = new ComparatorDateLis();
        Collections.sort(lisModels,c);

        return lisModels;
    }
}
